<template>
    <div class="sc-cropper">
        <div class="sc-cropper__img">
            <img :src="src" ref="imgRef">
        </div>
        <div class="sc-cropper__preview">
            <h4>{{ $t('upload.imageView') }}</h4>
            <div class="sc-cropper__preview__img" ref="previewRef"></div>
        </div>
    </div>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';

// 定义组件的 props
const props = defineProps({
    src: { type: String, default: "" }, // 图片源 URL
    compress: { type: Number, default: 1 }, // 图片压缩质量
    aspectRatio: { type: Number, default: NaN }, // 图片裁剪的宽高比
});
const crop = ref(null); // 裁剪实例的引用
const imgRef = ref(null); // 图片 DOM 元素的引用
const previewRef = ref(null); // 预览区域 DOM 元素的引用

// 监听 aspectRatio 的变化，当 aspectRatio 属性变化时，更新裁剪框的宽高比
watch(() => props.aspectRatio, (newVal) => {
    if (crop.value) {
        crop.value.setAspectRatio(newVal);
    }
}, { deep: true });
// 组件挂载后初始化 Cropper 实例
onMounted(() => {
    init();
});
// 初始化裁剪实例
const init = () => {
    crop.value = new Cropper(imgRef.value, {
        viewMode: 2,
        dragMode: 'move',
        responsive: false,
        aspectRatio: props.aspectRatio,
        preview: previewRef.value
    });
};
// 设置裁剪框的宽高比
const setAspectRatio = (aspectRatio) => {
    if (crop.value) {
        crop.value.setAspectRatio(aspectRatio);
    }
};
// 获取裁剪后的图像数据（Base64 格式）
const getCropData = (cb, type = 'image/jpeg') => {
    if (crop.value) {
        cb(crop.value.getCroppedCanvas().toDataURL(type, props.compress));
    }
};
// 获取裁剪后的图像数据（Blob 格式）
const getCropBlob = (cb, type = 'image/jpeg') => {
    if (crop.value) {
        crop.value.getCroppedCanvas().toBlob((blob) => {
            cb(blob);
        }, type, props.compress);
    }
};
// 获取裁剪后的图像数据（File 格式）
const getCropFile = (cb, fileName = 'fileName.jpg', type = 'image/jpeg') => {
    if (crop.value) {
        crop.value.getCroppedCanvas().toBlob((blob) => {
            let file = new File([blob], fileName, { type: type });
            cb(file);
        }, type, props.compress);
    }
};
// 暴露给父组件的方法
defineExpose({ setAspectRatio, getCropData, getCropBlob, getCropFile });
</script>